Proper connect_port
[juce-lv2.git] / juce / source / extras / the jucer / src / model / components / jucer_TabbedComponentHandler.h
blob9a4132cc3ef5e714994d1691d7c03be3c4907e54
1 /*
2 ==============================================================================
4 This file is part of the JUCE library - "Jules' Utility Class Extensions"
5 Copyright 2004-11 by Raw Material Software Ltd.
7 ------------------------------------------------------------------------------
9 JUCE can be redistributed and/or modified under the terms of the GNU General
10 Public License (Version 2), as published by the Free Software Foundation.
11 A copy of the license is included in the JUCE distribution, or can be found
12 online at www.gnu.org/licenses.
14 JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
15 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 A PARTICULAR PURPOSE. See the GNU General Public License for more details.
18 ------------------------------------------------------------------------------
20 To release a closed-source product which uses JUCE, commercial licenses are
21 available: visit www.rawmaterialsoftware.com/juce for more information.
23 ==============================================================================
26 #ifndef __JUCER_TABBEDCOMPONENTHANDLER_JUCEHEADER__
27 #define __JUCER_TABBEDCOMPONENTHANDLER_JUCEHEADER__
30 //==============================================================================
31 /**
33 class TabbedComponentHandler : public ComponentTypeHandler
35 public:
36 //==============================================================================
37 TabbedComponentHandler()
38 : ComponentTypeHandler ("Tabbed Component", "TabbedComponent", typeid (TabbedComponent), 200, 150)
41 //==============================================================================
42 Component* createNewComponent (JucerDocument*)
44 TabbedComponent* const t = new TabbedComponent (TabbedButtonBar::TabsAtTop);
45 t->setName ("new tabbed component");
47 for (int i = 3; --i >= 0;)
48 addNewTab (t);
50 return t;
53 XmlElement* createXmlFor (Component* comp, const ComponentLayout* layout)
55 TabbedComponent* const t = dynamic_cast <TabbedComponent*> (comp);
56 XmlElement* const e = ComponentTypeHandler::createXmlFor (comp, layout);
58 if (t->getOrientation() == TabbedButtonBar::TabsAtTop)
59 e->setAttribute ("orientation", "top");
60 else if (t->getOrientation() == TabbedButtonBar::TabsAtBottom)
61 e->setAttribute ("orientation", "bottom");
62 else if (t->getOrientation() == TabbedButtonBar::TabsAtLeft)
63 e->setAttribute ("orientation", "left");
64 else if (t->getOrientation() == TabbedButtonBar::TabsAtRight)
65 e->setAttribute ("orientation", "right");
67 e->setAttribute ("tabBarDepth", t->getTabBarDepth());
68 e->setAttribute ("initialTab", t->getCurrentTabIndex());
70 for (int i = 0; i < t->getNumTabs(); ++i)
71 e->addChildElement (getTabState (t, i));
73 return e;
76 bool restoreFromXml (const XmlElement& xml, Component* comp, const ComponentLayout* layout)
78 if (! ComponentTypeHandler::restoreFromXml (xml, comp, layout))
79 return false;
81 TabbedComponent* const t = dynamic_cast <TabbedComponent*> (comp);
83 if (xml.getStringAttribute ("orientation") == "top")
84 t->setOrientation (TabbedButtonBar::TabsAtTop);
85 else if (xml.getStringAttribute ("orientation") == "bottom")
86 t->setOrientation (TabbedButtonBar::TabsAtBottom);
87 else if (xml.getStringAttribute ("orientation") == "left")
88 t->setOrientation (TabbedButtonBar::TabsAtLeft);
89 else if (xml.getStringAttribute ("orientation") == "right")
90 t->setOrientation (TabbedButtonBar::TabsAtRight);
92 TabbedComponent defaultTabComp (TabbedButtonBar::TabsAtTop);
94 t->setTabBarDepth (xml.getIntAttribute ("tabBarDepth", defaultTabComp.getTabBarDepth()));
96 t->clearTabs();
98 forEachXmlChildElement (xml, e)
100 addNewTab (t);
101 restoreTabState (t, t->getNumTabs() - 1, *e);
104 t->setCurrentTabIndex (xml.getIntAttribute ("initialTab", 0));
106 return true;
109 void getEditableProperties (Component* component, JucerDocument& document, Array <PropertyComponent*>& properties)
111 ComponentTypeHandler::getEditableProperties (component, document, properties);
113 TabbedComponent* const t = dynamic_cast <TabbedComponent*> (component);
115 properties.add (new TabOrientationProperty (t, document));
116 properties.add (new TabDepthProperty (t, document));
118 if (t->getNumTabs() > 0)
119 properties.add (new TabInitialTabProperty (t, document));
121 properties.add (new TabAddTabProperty (t, document));
123 if (t->getNumTabs() > 0)
124 properties.add (new TabRemoveTabProperty (t, document));
127 void addPropertiesToPropertyPanel (Component* comp,
128 JucerDocument& document,
129 PropertyPanel& panel)
131 ComponentTypeHandler::addPropertiesToPropertyPanel (comp, document, panel);
133 TabbedComponent* const t = dynamic_cast <TabbedComponent*> (comp);
135 for (int i = 0; i < t->getNumTabs(); ++i)
137 Array <PropertyComponent*> properties;
139 properties.add (new TabNameProperty (t, document, i));
140 properties.add (new TabColourProperty (t, document, i));
142 properties.add (new TabContentTypeProperty (t, document, i));
144 if (isTabUsingJucerComp (t, i))
145 properties.add (new TabJucerFileProperty (t, document, i));
146 else
147 properties.add (new TabContentClassProperty (t, document, i));
149 properties.add (new TabContentConstructorParamsProperty (t, document, i));
151 properties.add (new TabMoveProperty (t, document, i, t->getNumTabs()));
153 panel.addSection ("Tab " + String (i), properties);
157 const String getCreationParameters (Component* comp)
159 TabbedComponent* const t = dynamic_cast <TabbedComponent*> (comp);
161 switch (t->getOrientation())
163 case TabbedButtonBar::TabsAtTop:
164 return "TabbedButtonBar::TabsAtTop";
165 case TabbedButtonBar::TabsAtBottom:
166 return "TabbedButtonBar::TabsAtBottom";
167 case TabbedButtonBar::TabsAtLeft:
168 return "TabbedButtonBar::TabsAtLeft";
169 case TabbedButtonBar::TabsAtRight:
170 return "TabbedButtonBar::TabsAtRight";
171 default:
172 jassertfalse
173 break;
176 return String::empty;
179 void fillInCreationCode (GeneratedCode& code, Component* component, const String& memberVariableName)
181 TabbedComponent* const t = dynamic_cast <TabbedComponent*> (component);
183 ComponentTypeHandler::fillInCreationCode (code, component, memberVariableName);
185 code.constructorCode
186 << memberVariableName << "->setTabBarDepth (" << t->getTabBarDepth() << ");\n";
188 for (int i = 0; i < t->getNumTabs(); ++i)
190 String contentClassName;
192 if (isTabUsingJucerComp (t, i))
194 JucerDocument* doc
195 = ObjectTypes::loadDocumentFromFile (code.document->getFile()
196 .getSiblingFile (getTabJucerFile (t, i)), false);
198 if (doc != 0)
200 code.includeFilesCPP.add (getTabJucerFile (t, i).replace (".cpp", ".h"));
202 contentClassName = doc->getClassName();
203 delete doc;
206 else
208 contentClassName = getTabClassName (t, i);
211 code.constructorCode
212 << memberVariableName
213 << "->addTab ("
214 << quotedString (t->getTabNames() [i])
215 << ", "
216 << colourToCode (t->getTabBackgroundColour (i));
218 if (contentClassName.isNotEmpty())
220 code.constructorCode << ", new " << contentClassName;
222 if (getTabConstructorParams (t, i).trim().isNotEmpty())
223 code.constructorCode << " ";
225 code.constructorCode << "(" << getTabConstructorParams (t, i).trim() << "), true);\n";
227 else
229 code.constructorCode << ", 0, false);\n";
233 code.constructorCode
234 << memberVariableName << "->setCurrentTabIndex (" << t->getCurrentTabIndex() << ");\n";
236 code.constructorCode << "\n";
239 //==============================================================================
240 static void addNewTab (TabbedComponent* tc, const int insertIndex = -1)
242 tc->addTab ("Tab " + String (tc->getNumTabs()), Colours::lightgrey,
243 new TabDemoContentComp(), true, insertIndex);
246 //==============================================================================
247 static XmlElement* getTabState (TabbedComponent* tc, int tabIndex)
249 XmlElement* xml = new XmlElement ("TAB");
250 xml->setAttribute ("name", tc->getTabNames() [tabIndex]);
251 setColourXml (*xml, "colour", tc->getTabBackgroundColour (tabIndex));
253 TabDemoContentComp* const tdc = dynamic_cast <TabDemoContentComp*> (tc->getTabContentComponent (tabIndex));
254 jassert (tdc != 0);
256 if (tdc != 0)
258 xml->setAttribute ("useJucerComp", tdc->isUsingJucerComp);
259 xml->setAttribute ("contentClassName", tdc->contentClassName);
260 xml->setAttribute ("constructorParams", tdc->constructorParams);
261 xml->setAttribute ("jucerComponentFile", tdc->jucerComponentFile);
264 return xml;
267 static void restoreTabState (TabbedComponent* tc, int tabIndex, const XmlElement& xml)
269 tc->setTabName (tabIndex, xml.getStringAttribute ("name", "Tab"));
270 tc->setTabBackgroundColour (tabIndex, getColourXml (xml, "colour", Colours::lightgrey));
272 TabDemoContentComp* const tdc = dynamic_cast <TabDemoContentComp*> (tc->getTabContentComponent (tabIndex));
273 jassert (tdc != 0);
275 if (tdc != 0)
277 tdc->isUsingJucerComp = xml.getBoolAttribute ("useJucerComp", false);
278 tdc->contentClassName = xml.getStringAttribute ("contentClassName");
279 tdc->constructorParams = xml.getStringAttribute ("constructorParams");
280 tdc->jucerComponentFile = xml.getStringAttribute ("jucerComponentFile");
282 tdc->updateContent();
286 //==============================================================================
287 static bool isTabUsingJucerComp (TabbedComponent* tc, int tabIndex)
289 TabDemoContentComp* const tdc = dynamic_cast <TabDemoContentComp*> (tc->getTabContentComponent (tabIndex));
290 jassert (tdc != 0);
292 return tdc != 0 && tdc->isUsingJucerComp;
295 static void setTabUsingJucerComp (TabbedComponent* tc, int tabIndex, const bool b)
297 TabDemoContentComp* const tdc = dynamic_cast <TabDemoContentComp*> (tc->getTabContentComponent (tabIndex));
298 jassert (tdc != 0);
300 if (tdc != 0)
302 tdc->isUsingJucerComp = b;
303 tdc->updateContent();
307 static const String getTabClassName (TabbedComponent* tc, int tabIndex)
309 TabDemoContentComp* const tdc = dynamic_cast <TabDemoContentComp*> (tc->getTabContentComponent (tabIndex));
310 jassert (tdc != 0);
312 return tdc != 0 ? tdc->contentClassName : String::empty;
315 static void setTabClassName (TabbedComponent* tc, int tabIndex, const String& newName)
317 TabDemoContentComp* const tdc = dynamic_cast <TabDemoContentComp*> (tc->getTabContentComponent (tabIndex));
318 jassert (tdc != 0);
320 if (tdc != 0)
322 tdc->contentClassName = newName;
323 tdc->updateContent();
327 static const String getTabConstructorParams (TabbedComponent* tc, int tabIndex)
329 TabDemoContentComp* const tdc = dynamic_cast <TabDemoContentComp*> (tc->getTabContentComponent (tabIndex));
330 jassert (tdc != 0);
332 return tdc != 0 ? tdc->constructorParams : String::empty;
335 static void setTabConstructorParams (TabbedComponent* tc, int tabIndex, const String& newParams)
337 TabDemoContentComp* const tdc = dynamic_cast <TabDemoContentComp*> (tc->getTabContentComponent (tabIndex));
338 jassert (tdc != 0);
340 if (tdc != 0)
342 tdc->constructorParams = newParams;
343 tdc->updateContent();
347 static const String getTabJucerFile (TabbedComponent* tc, int tabIndex)
349 TabDemoContentComp* const tdc = dynamic_cast <TabDemoContentComp*> (tc->getTabContentComponent (tabIndex));
350 jassert (tdc != 0);
352 return tdc != 0 ? tdc->jucerComponentFile : String::empty;
355 static void setTabJucerFile (TabbedComponent* tc, int tabIndex, const String& newFile)
357 TabDemoContentComp* const tdc = dynamic_cast <TabDemoContentComp*> (tc->getTabContentComponent (tabIndex));
358 jassert (tdc != 0);
360 if (tdc != 0)
362 tdc->jucerComponentFile = newFile;
363 tdc->updateContent();
367 private:
368 //==============================================================================
369 class TabDemoContentComp : public Component
371 public:
372 TabDemoContentComp()
373 : isUsingJucerComp (false)
375 setSize (2048, 2048);
378 ~TabDemoContentComp()
380 deleteAllChildren();
383 void paint (Graphics& g)
385 if (getNumChildComponents() == 0)
387 g.fillCheckerBoard (getLocalBounds(), 50, 50,
388 Colour::greyLevel (0.9f).withAlpha (0.4f),
389 Colour::greyLevel (0.8f).withAlpha (0.4f));
393 void resized()
395 Component* const c = getChildComponent (0);
397 if (c != 0)
399 c->setBounds (0, 0, getWidth(), getHeight());
400 setOpaque (c->isOpaque());
404 void updateContent()
406 if (isUsingJucerComp)
408 TestComponent* jucerComp = dynamic_cast <TestComponent*> (getChildComponent (0));
410 if (jucerComp == 0
411 || jucerComp->getOwnerDocument() == 0
412 || jucerComp->getFilename() != jucerComponentFile)
414 deleteAllChildren();
416 TestComponent* tc = new TestComponent (ComponentTypeHandler::findParentDocument (this), 0, false);
417 tc->setFilename (jucerComponentFile);
418 tc->setToInitialSize();
420 addAndMakeVisible (tc);
423 else
425 deleteAllChildren();
428 resized();
431 void parentHierarchyChanged()
433 updateContent();
436 bool isUsingJucerComp;
437 String contentClassName, constructorParams;
438 String jucerComponentFile;
441 //==============================================================================
442 class TabOrientationProperty : public ComponentChoiceProperty <TabbedComponent>
444 public:
445 TabOrientationProperty (TabbedComponent* comp, JucerDocument& document)
446 : ComponentChoiceProperty <TabbedComponent> ("tab position", comp, document)
448 choices.add ("Tabs at top");
449 choices.add ("Tabs at bottom");
450 choices.add ("Tabs at left");
451 choices.add ("Tabs at right");
454 void setIndex (int newIndex)
456 const TabbedButtonBar::Orientation orientations[] = { TabbedButtonBar::TabsAtTop,
457 TabbedButtonBar::TabsAtBottom,
458 TabbedButtonBar::TabsAtLeft,
459 TabbedButtonBar::TabsAtRight };
461 document.perform (new TabOrienationChangeAction (component, *document.getComponentLayout(), orientations [newIndex]),
462 "Change TabComponent orientation");
465 int getIndex() const
467 switch (component->getOrientation())
469 case TabbedButtonBar::TabsAtTop:
470 return 0;
471 case TabbedButtonBar::TabsAtBottom:
472 return 1;
473 case TabbedButtonBar::TabsAtLeft:
474 return 2;
475 case TabbedButtonBar::TabsAtRight:
476 return 3;
477 default:
478 jassertfalse
479 break;
482 return 0;
485 private:
486 class TabOrienationChangeAction : public ComponentUndoableAction <TabbedComponent>
488 public:
489 TabOrienationChangeAction (TabbedComponent* const comp, ComponentLayout& layout, const TabbedButtonBar::Orientation newState_)
490 : ComponentUndoableAction <TabbedComponent> (comp, layout),
491 newState (newState_)
493 oldState = comp->getOrientation();
496 bool perform()
498 showCorrectTab();
499 getComponent()->setOrientation (newState);
500 changed();
501 return true;
504 bool undo()
506 showCorrectTab();
507 getComponent()->setOrientation (oldState);
508 changed();
509 return true;
512 TabbedButtonBar::Orientation newState, oldState;
516 //==============================================================================
517 class TabInitialTabProperty : public ComponentChoiceProperty <TabbedComponent>
519 public:
520 TabInitialTabProperty (TabbedComponent* comp, JucerDocument& document)
521 : ComponentChoiceProperty <TabbedComponent> ("initial tab", comp, document)
523 for (int i = 0; i < comp->getNumTabs(); ++i)
524 choices.add ("Tab " + String (i) + ": \"" + comp->getTabNames() [i] + "\"");
527 void setIndex (int newIndex)
529 document.perform (new InitialTabChangeAction (component, *document.getComponentLayout(), newIndex),
530 "Change initial tab");
533 int getIndex() const
535 return component->getCurrentTabIndex();
538 private:
539 class InitialTabChangeAction : public ComponentUndoableAction <TabbedComponent>
541 public:
542 InitialTabChangeAction (TabbedComponent* const comp, ComponentLayout& layout, const int newValue_)
543 : ComponentUndoableAction <TabbedComponent> (comp, layout),
544 newValue (newValue_)
546 oldValue = comp->getCurrentTabIndex();
549 bool perform()
551 showCorrectTab();
552 getComponent()->setCurrentTabIndex (newValue);
553 changed();
554 return true;
557 bool undo()
559 showCorrectTab();
560 getComponent()->setCurrentTabIndex (oldValue);
561 changed();
562 return true;
565 private:
566 int newValue, oldValue;
570 //==============================================================================
571 class TabDepthProperty : public SliderPropertyComponent,
572 public ChangeListener
574 public:
575 TabDepthProperty (TabbedComponent* comp, JucerDocument& document_)
576 : SliderPropertyComponent ("tab depth", 10.0, 80.0, 1.0, 1.0),
577 component (comp),
578 document (document_)
580 document.addChangeListener (this);
583 ~TabDepthProperty()
585 document.removeChangeListener (this);
588 void setValue (double newValue)
590 document.getUndoManager().undoCurrentTransactionOnly();
592 document.perform (new TabDepthChangeAction (component, *document.getComponentLayout(), roundToInt (newValue)),
593 "Change TabComponent tab depth");
596 double getValue() const
598 return component->getTabBarDepth();
601 void changeListenerCallback (ChangeBroadcaster*)
603 refresh();
606 TabbedComponent* const component;
607 JucerDocument& document;
609 private:
610 class TabDepthChangeAction : public ComponentUndoableAction <TabbedComponent>
612 public:
613 TabDepthChangeAction (TabbedComponent* const comp, ComponentLayout& layout, const int newState_)
614 : ComponentUndoableAction <TabbedComponent> (comp, layout),
615 newState (newState_)
617 oldState = comp->getTabBarDepth();
620 bool perform()
622 showCorrectTab();
623 getComponent()->setTabBarDepth (newState);
624 changed();
625 return true;
628 bool undo()
630 showCorrectTab();
631 getComponent()->setTabBarDepth (oldState);
632 changed();
633 return true;
636 int newState, oldState;
640 //==============================================================================
641 class TabAddTabProperty : public ButtonPropertyComponent
643 public:
644 TabAddTabProperty (TabbedComponent* comp, JucerDocument& document_)
645 : ButtonPropertyComponent ("add tab", false),
646 component (comp),
647 document (document_)
651 void buttonClicked()
653 document.perform (new AddTabAction (component, *document.getComponentLayout()),
654 "Add a new tab");
657 const String getButtonText() const
659 return "Create a new tab";
662 TabbedComponent* const component;
663 JucerDocument& document;
665 private:
666 class AddTabAction : public ComponentUndoableAction <TabbedComponent>
668 public:
669 AddTabAction (TabbedComponent* const comp, ComponentLayout& layout)
670 : ComponentUndoableAction <TabbedComponent> (comp, layout)
674 bool perform()
676 showCorrectTab();
677 addNewTab (getComponent());
678 layout.getDocument()->refreshAllPropertyComps();
679 changed();
680 return true;
683 bool undo()
685 showCorrectTab();
686 getComponent()->removeTab (getComponent()->getNumTabs() - 1);
687 layout.getDocument()->refreshAllPropertyComps();
688 changed();
689 return true;
694 //==============================================================================
695 class TabRemoveTabProperty : public ButtonPropertyComponent
697 public:
698 TabRemoveTabProperty (TabbedComponent* comp, JucerDocument& document_)
699 : ButtonPropertyComponent ("remove tab", true),
700 component (comp),
701 document (document_)
705 void buttonClicked()
707 const StringArray names (component->getTabNames());
709 PopupMenu m;
710 for (int i = 0; i < component->getNumTabs(); ++i)
711 m.addItem (i + 1, "Delete tab " + String (i)
712 + ": \"" + names[i] + "\"");
714 const int r = m.showAt (this);
716 if (r > 0)
718 document.perform (new RemoveTabAction (component, *document.getComponentLayout(), r - 1),
719 "Remove a tab");
723 const String getButtonText() const
725 return "Delete a tab...";
728 TabbedComponent* const component;
729 JucerDocument& document;
731 private:
732 class RemoveTabAction : public ComponentUndoableAction <TabbedComponent>
734 public:
735 RemoveTabAction (TabbedComponent* const comp, ComponentLayout& layout, int indexToRemove_)
736 : ComponentUndoableAction <TabbedComponent> (comp, layout),
737 indexToRemove (indexToRemove_),
738 previousState (0)
740 previousState = getTabState (comp, indexToRemove);
743 ~RemoveTabAction()
745 delete previousState;
748 bool perform()
750 showCorrectTab();
752 getComponent()->removeTab (indexToRemove);
753 layout.getDocument()->refreshAllPropertyComps();
754 changed();
755 return true;
758 bool undo()
760 showCorrectTab();
761 addNewTab (getComponent(), indexToRemove);
762 restoreTabState (getComponent(), indexToRemove, *previousState);
763 layout.getDocument()->refreshAllPropertyComps();
764 changed();
765 return true;
768 private:
769 int indexToRemove;
770 XmlElement* previousState;
774 //==============================================================================
775 class TabNameProperty : public ComponentTextProperty <TabbedComponent>
777 public:
778 TabNameProperty (TabbedComponent* comp, JucerDocument& document, const int tabIndex_)
779 : ComponentTextProperty <TabbedComponent> ("name", 200, false, comp, document),
780 tabIndex (tabIndex_)
784 void setText (const String& newText)
786 document.perform (new TabNameChangeAction (component, *document.getComponentLayout(), tabIndex, newText),
787 "Change tab name");
790 const String getText() const
792 return component->getTabNames() [tabIndex];
795 private:
796 int tabIndex;
798 class TabNameChangeAction : public ComponentUndoableAction <TabbedComponent>
800 public:
801 TabNameChangeAction (TabbedComponent* const comp, ComponentLayout& layout, const int tabIndex_, const String& newValue_)
802 : ComponentUndoableAction <TabbedComponent> (comp, layout),
803 tabIndex (tabIndex_),
804 newValue (newValue_)
806 oldValue = comp->getTabNames() [tabIndex];
809 bool perform()
811 showCorrectTab();
812 getComponent()->setTabName (tabIndex, newValue);
813 changed();
814 return true;
817 bool undo()
819 showCorrectTab();
820 getComponent()->setTabName (tabIndex, oldValue);
821 changed();
822 return true;
825 private:
826 const int tabIndex;
827 String newValue, oldValue;
831 //==============================================================================
832 class TabColourProperty : public ColourPropertyComponent,
833 private ChangeListener
835 public:
836 TabColourProperty (TabbedComponent* comp, JucerDocument& document_, const int tabIndex_)
837 : ColourPropertyComponent ("colour", false),
838 component (comp),
839 document (document_),
840 tabIndex (tabIndex_)
842 document.addChangeListener (this);
845 ~TabColourProperty()
847 document.removeChangeListener (this);
850 void setColour (const Colour& newColour)
852 document.getUndoManager().undoCurrentTransactionOnly();
854 document.perform (new TabColourChangeAction (component, *document.getComponentLayout(), tabIndex, newColour),
855 "Change tab colour");
858 const Colour getColour() const
860 return component->getTabBackgroundColour (tabIndex);
863 void resetToDefault()
865 jassertfalse // shouldn't get called
868 void changeListenerCallback (ChangeBroadcaster*) { refresh(); }
870 private:
871 TabbedComponent* component;
872 JucerDocument& document;
873 int tabIndex;
875 class TabColourChangeAction : public ComponentUndoableAction <TabbedComponent>
877 public:
878 TabColourChangeAction (TabbedComponent* const comp, ComponentLayout& layout, const int tabIndex_, const Colour& newValue_)
879 : ComponentUndoableAction <TabbedComponent> (comp, layout),
880 tabIndex (tabIndex_),
881 newValue (newValue_)
883 oldValue = comp->getTabBackgroundColour (tabIndex);
886 bool perform()
888 showCorrectTab();
889 getComponent()->setTabBackgroundColour (tabIndex, newValue);
890 changed();
891 return true;
894 bool undo()
896 showCorrectTab();
897 getComponent()->setTabBackgroundColour (tabIndex, oldValue);
898 changed();
899 return true;
902 private:
903 const int tabIndex;
904 Colour newValue, oldValue;
908 //==============================================================================
909 class TabContentTypeProperty : public ComponentChoiceProperty <TabbedComponent>
911 public:
912 TabContentTypeProperty (TabbedComponent* comp, JucerDocument& document, const int tabIndex_)
913 : ComponentChoiceProperty <TabbedComponent> ("content type", comp, document),
914 tabIndex (tabIndex_)
916 choices.add ("Jucer content component");
917 choices.add ("Named content component");
920 void setIndex (int newIndex)
922 document.perform (new TabContentTypeChangeAction (component, *document.getComponentLayout(), tabIndex, newIndex == 0),
923 "Change tab content type");
926 int getIndex() const
928 return isTabUsingJucerComp (component, tabIndex) ? 0 : 1;
931 private:
932 int tabIndex;
934 class TabContentTypeChangeAction : public ComponentUndoableAction <TabbedComponent>
936 public:
937 TabContentTypeChangeAction (TabbedComponent* const comp, ComponentLayout& layout, const int tabIndex_, const bool newValue_)
938 : ComponentUndoableAction <TabbedComponent> (comp, layout),
939 tabIndex (tabIndex_),
940 newValue (newValue_)
942 oldValue = isTabUsingJucerComp (comp, tabIndex);
945 bool perform()
947 showCorrectTab();
948 setTabUsingJucerComp (getComponent(), tabIndex, newValue);
949 layout.getDocument()->refreshAllPropertyComps();
950 changed();
951 return true;
954 bool undo()
956 showCorrectTab();
957 setTabUsingJucerComp (getComponent(), tabIndex, oldValue);
958 layout.getDocument()->refreshAllPropertyComps();
959 changed();
960 return true;
963 private:
964 int tabIndex;
965 bool newValue, oldValue;
969 //==============================================================================
970 class TabJucerFileProperty : public FilePropertyComponent,
971 public ChangeListener
973 public:
974 TabJucerFileProperty (TabbedComponent* const component_, JucerDocument& document_, const int tabIndex_)
975 : FilePropertyComponent ("jucer file", false, true),
976 component (component_),
977 document (document_),
978 tabIndex (tabIndex_)
980 document.addChangeListener (this);
983 ~TabJucerFileProperty()
985 document.removeChangeListener (this);
988 //==============================================================================
989 void setFile (const File& newFile)
991 document.perform (new JucerCompFileChangeAction (component, *document.getComponentLayout(), tabIndex,
992 newFile.getRelativePathFrom (document.getFile().getParentDirectory())
993 .replaceCharacter ('\\', '/')),
994 "Change tab component file");
997 const File getFile() const
999 return document.getFile().getSiblingFile (getTabJucerFile (component, tabIndex));
1002 void changeListenerCallback (ChangeBroadcaster*) { refresh(); }
1004 private:
1005 TabbedComponent* const component;
1006 JucerDocument& document;
1007 int tabIndex;
1009 class JucerCompFileChangeAction : public ComponentUndoableAction <TabbedComponent>
1011 public:
1012 JucerCompFileChangeAction (TabbedComponent* const comp, ComponentLayout& layout, const int tabIndex_, const String& newState_)
1013 : ComponentUndoableAction <TabbedComponent> (comp, layout),
1014 tabIndex (tabIndex_),
1015 newState (newState_)
1017 oldState = getTabJucerFile (comp, tabIndex);
1020 bool perform()
1022 showCorrectTab();
1023 setTabJucerFile (getComponent(), tabIndex, newState);
1024 changed();
1025 return true;
1028 bool undo()
1030 showCorrectTab();
1031 setTabJucerFile (getComponent(), tabIndex, oldState);
1032 changed();
1033 return true;
1036 int tabIndex;
1037 String newState, oldState;
1041 //==============================================================================
1042 class TabContentClassProperty : public ComponentTextProperty <TabbedComponent>
1044 public:
1045 TabContentClassProperty (TabbedComponent* comp, JucerDocument& document, const int tabIndex_)
1046 : ComponentTextProperty <TabbedComponent> ("content class", 256, false, comp, document),
1047 tabIndex (tabIndex_)
1051 void setText (const String& newText)
1053 document.perform (new TabClassNameChangeAction (component, *document.getComponentLayout(), tabIndex, newText),
1054 "Change TabbedComponent content class");
1057 const String getText() const
1059 return getTabClassName (component, tabIndex);
1062 private:
1063 int tabIndex;
1065 class TabClassNameChangeAction : public ComponentUndoableAction <TabbedComponent>
1067 public:
1068 TabClassNameChangeAction (TabbedComponent* const comp, ComponentLayout& layout, const int tabIndex_, const String& newValue_)
1069 : ComponentUndoableAction <TabbedComponent> (comp, layout),
1070 tabIndex (tabIndex_),
1071 newValue (newValue_)
1073 oldValue = getTabClassName (comp, tabIndex);
1076 bool perform()
1078 showCorrectTab();
1079 setTabClassName (getComponent(), tabIndex, newValue);
1080 changed();
1081 layout.getDocument()->refreshAllPropertyComps();
1082 return true;
1085 bool undo()
1087 showCorrectTab();
1088 setTabClassName (getComponent(), tabIndex, oldValue);
1089 changed();
1090 layout.getDocument()->refreshAllPropertyComps();
1091 return true;
1094 int tabIndex;
1095 String newValue, oldValue;
1099 //==============================================================================
1100 class TabContentConstructorParamsProperty : public ComponentTextProperty <TabbedComponent>
1102 public:
1103 TabContentConstructorParamsProperty (TabbedComponent* comp, JucerDocument& document, const int tabIndex_)
1104 : ComponentTextProperty <TabbedComponent> ("constructor params", 512, false, comp, document),
1105 tabIndex (tabIndex_)
1109 void setText (const String& newText)
1111 document.perform (new TabConstructorParamChangeAction (component, *document.getComponentLayout(), tabIndex, newText),
1112 "Change TabbedComponent content constructor param");
1115 const String getText() const
1117 return getTabConstructorParams (component, tabIndex);
1120 private:
1121 int tabIndex;
1123 class TabConstructorParamChangeAction : public ComponentUndoableAction <TabbedComponent>
1125 public:
1126 TabConstructorParamChangeAction (TabbedComponent* const comp, ComponentLayout& layout, const int tabIndex_, const String& newValue_)
1127 : ComponentUndoableAction <TabbedComponent> (comp, layout),
1128 tabIndex (tabIndex_),
1129 newValue (newValue_)
1131 oldValue = getTabConstructorParams (comp, tabIndex);
1134 bool perform()
1136 showCorrectTab();
1137 setTabConstructorParams (getComponent(), tabIndex, newValue);
1138 changed();
1139 layout.getDocument()->refreshAllPropertyComps();
1140 return true;
1143 bool undo()
1145 showCorrectTab();
1146 setTabConstructorParams (getComponent(), tabIndex, oldValue);
1147 changed();
1148 layout.getDocument()->refreshAllPropertyComps();
1149 return true;
1152 int tabIndex;
1153 String newValue, oldValue;
1157 //==============================================================================
1158 class TabMoveProperty : public ButtonPropertyComponent
1160 public:
1161 TabMoveProperty (TabbedComponent* comp, JucerDocument& document_,
1162 const int tabIndex_, const int totalNumTabs_)
1163 : ButtonPropertyComponent ("move tab", false),
1164 component (comp),
1165 document (document_),
1166 tabIndex (tabIndex_),
1167 totalNumTabs (totalNumTabs_)
1172 void buttonClicked()
1174 PopupMenu m;
1175 m.addItem (1, "Move this tab up", tabIndex > 0);
1176 m.addItem (2, "Move this tab down", tabIndex < totalNumTabs - 1);
1178 const int r = m.showAt (this);
1180 if (r != 0)
1182 document.perform (new MoveTabAction (component, *document.getComponentLayout(), tabIndex, tabIndex + (r == 2 ? 1 : -1)),
1183 "Move a tab");
1187 const String getButtonText() const
1189 return "Move this tab...";
1192 TabbedComponent* const component;
1193 JucerDocument& document;
1194 const int tabIndex, totalNumTabs;
1196 private:
1197 class MoveTabAction : public ComponentUndoableAction <TabbedComponent>
1199 public:
1200 MoveTabAction (TabbedComponent* const comp, ComponentLayout& layout,
1201 const int oldIndex_, const int newIndex_)
1202 : ComponentUndoableAction <TabbedComponent> (comp, layout),
1203 oldIndex (oldIndex_),
1204 newIndex (newIndex_)
1208 void move (int from, int to)
1210 showCorrectTab();
1212 XmlElement* const state = getTabState (getComponent(), from);
1214 getComponent()->removeTab (from);
1215 addNewTab (getComponent(), to);
1217 restoreTabState (getComponent(), to, *state);
1218 delete state;
1220 layout.getDocument()->refreshAllPropertyComps();
1221 changed();
1224 bool perform()
1226 move (oldIndex, newIndex);
1227 return true;
1230 bool undo()
1232 move (newIndex, oldIndex);
1233 return true;
1236 private:
1237 const int oldIndex, newIndex;
1243 #endif // __JUCER_TABBEDCOMPONENTHANDLER_JUCEHEADER__